package com.epam.training.concurrency.second.task4;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Test series
 * 
 * @author bogdan
 *
 */
public class Test {

	public final static int POOL_THREAD_NUMBER = 10;
	public final static int EXECUTE_THREAD_NUMBER = 10000;

	private Test() {

	}

	public static void main(String[] args) {
		testDuplicate();
	}

	/**
	 * Check for duplicate test
	 */
	public static void testDuplicate() {
		ExecutorService executor = Executors
				.newFixedThreadPool(POOL_THREAD_NUMBER);

		List<Future<BigInteger>> list = new LinkedList<Future<BigInteger>>();

		for (int i = 0; i < EXECUTE_THREAD_NUMBER; i++) {
			list.add(executor.submit(new TestThread()));
		}

		List<BigInteger> number = new ArrayList<BigInteger>();

		for (int i = 0; i < EXECUTE_THREAD_NUMBER; i++) {
			try {
				number.add(((LinkedList<Future<BigInteger>>) list)
						.removeFirst().get());
			} catch (InterruptedException | ExecutionException e) {
				Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null,
						e);
			}
		}

		if (duplicate(number)) {
			Logger.getLogger(Test.class.getName()).log(Level.SEVERE,
					"Duplicate numbers!!");
		} else {
			Logger.getLogger(Test.class.getName()).log(Level.INFO,
					"no duplicate number");
		}

		executor.shutdown();
	}

	/**
	 * 
	 * @param list
	 * @return
	 */
	public static boolean duplicate(List<BigInteger> list) {
		BigInteger[] num = new BigInteger[list.size()];
		num = list.toArray(num);

		for (int i = 0; i < num.length; i++) {
			for (int j = 0; j < num.length; j++) {
				if (num[i].equals(num[j]) && (i != j)) {
					return true;
				}
			}
		}

		return false;
	}
}
